﻿#pragma once

#ifndef ROOTRPC_EXPORTED
// This means the client library is being consumed by an app
#define ROOTRPC_EXPORTED __declspec(dllimport)
#pragma comment(lib, "RootRpcClient.lib")
// Assume that the client does not want APIs unless specified (they can break builds)
#ifdef ROOTRPC_ALL_APIS
#define ROOTRPC_FILE_APIS
#define ROOTRPC_DRIVE_APIS
#define ROOTRPC_REG_APIS
#define ROOTRPC_PROCESS_APIS
#define ROOTRPC_PIPE_APIS
#define ROOTRPC_SERVICE_APIS
#endif
#ifndef ROOTRPC_FILE_APIS
#define NO_ROOTRPC_FILE_APIS
#endif
#ifndef ROOTRPC_DRIVE_APIS
#define NO_ROOTRPC_DRIVE_APIS
#endif
#ifndef ROOTRPC_REG_APIS
#define NO_ROOTRPC_REG_APIS
#endif
#ifndef ROOTRPC_PROCESS_APIS
#define NO_ROOTRPC_PROCESS_APIS
#endif
#ifndef ROOTRPC_PIPE_APIS
#define NO_ROOTRPC_PIPE_APIS
#endif
#ifndef ROOTRPC_SERVICE_APIS
#define NO_ROOTRPC_SERVICE_APIS
#endif
#endif

#ifdef ROOTRPC_REPLACEMENTS

#ifndef NO_ROOTRPC_FILE_APIS
#ifdef CopyFile
#undef CopyFile
#endif
#define CopyFile RootCopyFile

#ifdef CopyFile2
#undef CopyFile2
#endif
#define CopyFile2 RootCopyFile2

#ifdef CreateFile
#undef CreateFile
#endif
#define CreateFile RootCreateFile

#ifdef CreateFile2
#undef CreateFile2
#endif
#define CreateFile2 RootCreateFile2

#ifdef CreateHardLink
#undef CreateHardLink
#endif
#define CreateHardLink RootCreateHardLink

#ifdef CreateSymbolicLink
#undef CreateSymbolicLink
#endif
#define CreateSymbolicLink RootCreateSymbolicLink

#ifdef DeleteFile
#undef DeleteFile
#endif
#define DeleteFile RootDeleteFile

#ifdef FindCLose
#undef FindClose
#endif
#define FindClose RootFindClose

#ifdef FindFirstFile
#undef FindFirstFile
#endif
#define FindFirstFile RootFindFirstFile

#ifdef FindFirstFileEx
#undef FindFirstFileEx
#endif
#define FindFirstFileEx RootFindFirstFileEx

#ifdef FindNextFile
#undef FindNextFile
#endif
#define FindNextFile RootFindNextFile

#ifdef GetFileAttributes
#undef GetFileAttributes
#endif
#define GetFileAttributes RootGetFileAttributes

#ifdef GetFileAttributesEx
#undef GetFileAttributesEx
#endif
#define GetFileAttributesEx RootGetFileAttributesEx

#ifdef MoveFile
#undef MoveFile
#endif
#define MoveFile RootMoveFile

#ifdef MoveFileEx
#undef MoveFileEx
#define MoveFileEx RootMoveFileEx
#endif
#ifdef ReplaceFile
#undef ReplaceFile
#endif
#define ReplaceFile RootReplaceFile

//REWRAP(SearchPath)
#ifdef SetFileAttributes
#undef SetFileAttributes
#endif
#define SetFileAttributes RootSetFileAttributes

#ifdef CreateDirectory
#undef CreateDirectory
#endif
#define CreateDirectory RootCreateDirectory

#ifdef CreateDirectoryEx
#undef CreateDirectoryEx
#endif
#define CreateDirectoryEx RootCreateDirectoryEx

#ifdef FindFirstChangeNotification
#undef FindFirstChangeNotification
#endif
#define FindFirstChangeNotification RootFindFirstChangeNotification

#ifdef RemoveDirectory
#undef RemoveDirectory
#endif
#define RemoveDirectory RootRemoveDirectory
#endif	// NO_ROOTRPC_FILE_APIS

#ifndef NO_ROOTRPC_DRIVE_APIS
// DosDevice, FindVolume, FindVolMountPoint go here

#ifdef GetDriveType
#undef GetDriveType
#endif
#define GetDriveType RootGetDriveType

// Volume, DosDevice go here
#endif

#ifndef NO_ROOTRPC_REG_APIS
#ifdef RegCreateKeyEx
#undef RegCreateKeyEx
#endif
#define RegCreateKeyEx RootRegCreateKeyEx

#ifdef RegCopyTree
#undef RegCopyTree
#endif
#define RegCopyTree RootRegCopyTree

#ifdef RegDeleteKey
#undef RegDeleteKey
#endif
#define RegDeleteKey RootRegDeleteKey

#ifdef RegDeleteKeyEx
#undef RegDeleteKeyEx
#endif
#define RegDeleteKeyEx RootRegDeleteKeyEx

#ifdef RegDeleteKeyValue
#undef RegDeleteKeyValue
#endif
#define RegDeleteKeyValue RootRegDeleteKeyValue

#ifdef RegDeleteTree
#undef RegDeleteTree
#endif
#define RegDeleteTree RootRegDeleteTree

#ifdef RegGetValue
#undef RegGetValue
#endif
#define RegGetValue RootRegGetValue

//REWRAP(RegLoadKey)
//REWRAP(RegOpenCurrentUser)
#ifdef RegOpenKeyEx
#undef RegOpenKeyEx
#endif
#define RegOpenKeyEx RootRegOpenKeyEx

#ifdef RegReplaceKey
#undef RegReplaceKey
#endif
#define RegReplaceKey RootRegReplaceKey

#ifdef RegRestoreKey
#undef RegRestoreKey
#endif
#define RegRestoreKey RootRegRestoreKey

#ifdef RegSaveKey
#undef RegSaveKey
#endif
#define RegSaveKey RootRegSaveKey

#ifdef RegSaveKeyEx
#undef RegSaveKeyEx
#endif
#define RegSaveKeyEx RootRegSaveKeyEx

#ifdef RegSetKeyValue
#undef RegSetKeyValue
#endif
#define RegSetKeyValue RootRegSetKeyValue
#endif	// NO_ROOTRPC_REG_APIS

#ifndef NO_ROOTRPC_PROCESS_APIS
#ifdef CreateProcess
#undef CreateProcess
#endif
#define CreateProcess RootCreateProcess

#ifdef CreateProcessAsUser
#undef CreateProcessAsUser
#endif
#define CreateProcessAsUser RootCreateProcessAsUser

#ifdef CreateJobObject
#undef CreateJobObject
#endif
#define CreateJobObject RootCreateJobObject

#ifdef EnumProcesses
#undef EnumProcesses
#endif
#define EnumProcesses RootEnumProcesses

#ifdef OpenProcess
#undef OpenProcess
#endif
#define OpenProcess RootOpenProcess

#ifdef OpenThread
#undef OpenThread
#endif
#define OpenThread RootOpenThread
#endif
#endif

#ifdef __cplusplus
extern "C" {
#endif

typedef unsigned long WINERR;

/**
 * Contains the return value of the at-DLL-load initialization attempt.
 */
extern WINERR initStatus;

/**
 * Connect to the RootRpc server. Starts the service first if necessary.
 */
ROOTRPC_EXPORTED WINERR InitRootRpc();

/**
 * Release the RootRpc server, decrementing its client count. May cause the server to exit.
 * Do not call any Root* functions following successful completion of this function.
 * If the process exits without calling this function, the server may eventually exit anyhow.
 */
ROOTRPC_EXPORTED WINERR CloseRootRpc();

/**
 * Confirm that the server is listening for, and responding to, requests.
 */
ROOTRPC_EXPORTED WINERR TestRootRpc();

/**
 * Check the RootRpc initialization status (whether or not the client is connected).
 */
ROOTRPC_EXPORTED WINERR GetRootRpcInitStatus();

/**
 * Get the RootRpc client library version (should always match the server version).
 */
ROOTRPC_EXPORTED DWORD RpcClientVersion(
	PDWORD major,
	PDWORD minor,
	PDWORD bugfix);

/**
 * Get the server's version.
 * Returns the server revision, or 0xFFFFFFFF if an error occurs.
 */
ROOTRPC_EXPORTED DWORD RootServerVersion(
	PDWORD major,
	PDWORD minor,
	PDWORD bugfix);

/**
 * Gets a full-access HANDLE to the server process.
 */
ROOTRPC_EXPORTED HANDLE RootGetServerProcess();

/**
 * Gets a full-access HANDLE to the server process' token.
 */
ROOTRPC_EXPORTED HANDLE RootGetServerToken();

#ifndef NO_ROOTRPC_FILE_APIS
ROOTRPC_EXPORTED BOOL RootCopyFile(
	LPCWSTR lpExistingFileName,
	LPCWSTR lpNewFileName,
	BOOL bFailIfExists);
ROOTRPC_EXPORTED HRESULT RootCopyFile2(
	LPCWSTR pwszExistingFileName,
	LPCWSTR pwszNewFileName,
	COPYFILE2_EXTENDED_PARAMETERS * pExtendedParameters);
ROOTRPC_EXPORTED HANDLE RootCreateFile(
	LPCWSTR lpFileName,
	DWORD dwDesiredAccess,
	DWORD dwShareMode,
	LPSECURITY_ATTRIBUTES lpSecurityAttributes,
	DWORD dwCreationDisposition,
	DWORD dwFlagsAndAttributes,
	HANDLE hTemplateFile);
ROOTRPC_EXPORTED HANDLE RootCreateFile2(
	LPCWSTR lpFileName,
	DWORD dwDesiredAccess,
	DWORD dwShareMode,
	DWORD dwCreationDisposition,
	LPCREATEFILE2_EXTENDED_PARAMETERS pCreateExParams);
ROOTRPC_EXPORTED BOOL RootCreateHardLink(
	LPCWSTR lpFileName,
	LPCWSTR lpExistingFileName,
	LPSECURITY_ATTRIBUTES lpSecurityAttributes);
ROOTRPC_EXPORTED BOOLEAN RootCreateSymbolicLink(
	LPWSTR lpSymbolicFileName,
	LPWSTR lpTargetFileName,
	DWORD dwFlags);
ROOTRPC_EXPORTED BOOL RootDeleteFile(
	LPCWSTR lpFileName);
ROOTRPC_EXPORTED BOOL RootFindClose(
	HANDLE hFindFile);
ROOTRPC_EXPORTED HANDLE RootFindFirstFile(
	LPCWSTR lpFileName,
	LPWIN32_FIND_DATAW lpFindFileData);
ROOTRPC_EXPORTED HANDLE RootFindFirstFileEx(
	LPCWSTR lpFileName,
	FINDEX_INFO_LEVELS fInfoLevelId,
	PWIN32_FIND_DATAW lpFindFileData,
	FINDEX_SEARCH_OPS fSearchOp,
	LPVOID lpSearchFilter,
	DWORD dwAdditionalFlags);
ROOTRPC_EXPORTED BOOL RootFindNextFile(
	HANDLE hFindFile,
	LPWIN32_FIND_DATAW lpFindFileData);
ROOTRPC_EXPORTED DWORD RootGetFileAttributes(
	LPCWSTR lpFileName);
ROOTRPC_EXPORTED BOOL RootGetFileAttributesEx(
	LPCWSTR lpFileName,
	GET_FILEEX_INFO_LEVELS fInfoLevelId,
	LPWIN32_FILE_ATTRIBUTE_DATA lpFileInformation);
ROOTRPC_EXPORTED BOOL RootMoveFile(
	LPCWSTR lpExistingFileName,
	LPCWSTR lpNewFileName);
ROOTRPC_EXPORTED BOOL RootMoveFileEx(
	LPCWSTR lpExistingFileName,
	LPCWSTR lpNewFileName,
	DWORD dwFlags);
ROOTRPC_EXPORTED BOOL RootReplaceFile(
	LPCWSTR lpReplacedFileName,
	LPCWSTR lpReplacementFileName,
	LPCWSTR lpBackupFileName,
	DWORD dwReplaceFlags,
	LPVOID lpExclude,
	LPVOID lpReserved);
ROOTRPC_EXPORTED DWORD RootSearchPath(
	LPCWSTR lpPath,
	LPCWSTR lpFileName,
	LPCWSTR lpExtension,
	DWORD nBufferLength,
	LPWSTR lpBuffer,
	LPWSTR * lpFilePart);
ROOTRPC_EXPORTED BOOL RootSetFileAttributes(
	LPCWSTR lpFileName,
	DWORD dwFileAttributes);
ROOTRPC_EXPORTED BOOL RootCreateDirectory(
	LPCWSTR lpPathName,
	LPSECURITY_ATTRIBUTES lpSecurityAttributes);
ROOTRPC_EXPORTED BOOL RootCreateDirectoryEx(
	LPCWSTR lpTemplateDirectory,
	LPCWSTR lpNewDirectory,
	LPSECURITY_ATTRIBUTES lpSecurityAttributes);
ROOTRPC_EXPORTED HANDLE RootFindFirstChangeNotification(
	LPCWSTR lpPathName,
	BOOL bWatchSubtree,
	DWORD dwNotifyFilter);
ROOTRPC_EXPORTED BOOL RootRemoveDirectory(
	LPCWSTR lpPathName);
#endif
#ifndef NO_ROOTRPC_DRIVE_APIS
// TODO: All the DosDevice, FindVolume, and FindVMP stuff.
ROOTRPC_EXPORTED UINT RootGetDriveType(
	LPCWSTR lpRootPathName);
// TODO: All the Volume and DosDevice stuff.
#endif
#ifndef NO_ROOTRPC_REG_APIS
ROOTRPC_EXPORTED LONG RootRegCopyTree(
	HKEY hKeySrc,
	LPCWSTR lpSubKey,
	HKEY hKeyDest);
ROOTRPC_EXPORTED LONG RootRegCreateKeyEx(
	HKEY hKey,
	LPCWSTR lpSubKey,
	DWORD Reserved,
	LPWSTR lpClass,
	DWORD dwOptions,
	REGSAM samDesired,
	LPSECURITY_ATTRIBUTES lpSecurityAttributes,
	PHKEY phkResult,
	LPDWORD lpdwDisposition);
ROOTRPC_EXPORTED LONG RootRegDeleteKey(
	HKEY hKey,
	LPCWSTR lpSubKey);
ROOTRPC_EXPORTED LONG RootRegDeleteKeyEx(
	HKEY hKey,
	LPCWSTR lpSubKey,
	REGSAM samDesired,
	DWORD Reserved);
ROOTRPC_EXPORTED LONG RootRegDeleteKeyValue(
	HKEY hKey,
	LPCWSTR lpSubKey,
	LPCWSTR lpValueName);
ROOTRPC_EXPORTED LONG RootRegDeleteTree(
	HKEY hKey,
	LPCWSTR lpSubKey);
ROOTRPC_EXPORTED LONG RootRegGetValue(
	HKEY hKey,
	LPCTSTR lpSubKey,
	LPCTSTR lpValue,
	DWORD dwFlags,
	LPDWORD pdwType,
	PVOID pvData,
	LPDWORD pcbData);
ROOTRPC_EXPORTED LONG RootRegLoadKey(
	HKEY hKey,
	LPCWSTR lpSubKey,
	LPCWSTR lpFile);
ROOTRPC_EXPORTED LONG RootRegOpenCurrentUser(
	REGSAM samDesired,
	PHKEY phkResult);
ROOTRPC_EXPORTED LONG RootRegOpenKeyEx(
	HKEY hKey,
	LPCWSTR lpSubKey,
	DWORD ulOptions,
	REGSAM samDesired,
	PHKEY phkResult);
ROOTRPC_EXPORTED LONG RootRegReplaceKey(
	HKEY hKey,
	LPCWSTR lpSubKey,
	LPCWSTR lpNewFile,
	LPCWSTR lpOldFile);
ROOTRPC_EXPORTED LONG RootRegRestoreKey(
	HKEY hKey,
	LPCWSTR lpFile,
	DWORD dwFlags);
ROOTRPC_EXPORTED LONG RootRegSaveKey(
	HKEY hKey,
	LPCWSTR lpFile,
	LPSECURITY_ATTRIBUTES lpSecurityAttributes);
ROOTRPC_EXPORTED LONG RootRegSaveKeyEx(
	HKEY hKey,
	LPCWSTR lpFile,
	LPSECURITY_ATTRIBUTES lpSecurityAttributes,
	DWORD Flags);
ROOTRPC_EXPORTED LONG RootRegSetKeyValue(
	HKEY hKey,
	LPCWSTR lpSubKey,
	LPCWSTR lpValueName,
	DWORD dwType,
	LPCVOID lpData,
	DWORD cbData);
#endif
#ifndef NO_ROOTRPC_PROCESS_APIS
ROOTRPC_EXPORTED HANDLE RootCreateJobObject(
	LPSECURITY_ATTRIBUTES lpJobAttributes,
	LPCWSTR lpName);
ROOTRPC_EXPORTED BOOL RootCreateProcess(
	LPCWSTR lpApplicationName,
	LPWSTR lpCommandLine,
	LPSECURITY_ATTRIBUTES lpProcessAttributes,
	LPSECURITY_ATTRIBUTES lpThreadAttributes,
	BOOL bInheritHandles,
	DWORD dwCreationFlags,
	LPVOID lpEnvironment,
	LPCWSTR lpCurrentDirectory,
	LPSTARTUPINFOW lpStartupInfo,
	LPPROCESS_INFORMATION lpProcessInformation);
ROOTRPC_EXPORTED BOOL RootCreateProcessAsUser(
	HANDLE hToken,
	LPCWSTR lpApplicationName,
	LPWSTR lpCommandLine,
	LPSECURITY_ATTRIBUTES lpProcessAttributes,
	LPSECURITY_ATTRIBUTES lpThreadAttributes,
	BOOL bInheritHandles,
	DWORD dwCreationFlags,
	LPVOID lpEnvironment,
	LPCWSTR lpCurrentDirectory,
	LPSTARTUPINFOW lpStartupInfo,
	LPPROCESS_INFORMATION lpProcessInformation);
ROOTRPC_EXPORTED BOOL RootEnumProcesses(
	DWORD *pProcessIds,
	DWORD cb,
	DWORD *pBytesReturned);
ROOTRPC_EXPORTED HANDLE RootOpenJobObject(
	DWORD dwDesiredAccess,
	BOOL bInheritHandle,
	LPWSTR lpName);
ROOTRPC_EXPORTED HANDLE RootOpenProcess(
	DWORD dwDesiredAccess,
	BOOL bInheritHandle,
	DWORD dwProcessId);
ROOTRPC_EXPORTED HANDLE RootOpenThread(
	DWORD dwDesiredAccess,
	BOOL bInheritHandle,
	DWORD dwThreadId);
#endif
#ifndef NO_ROOTRPC_PIPE_APIS
ROOTRPC_EXPORTED BOOL RootCallNamedPipe(
	LPCWSTR lpNamedPipeName,
	LPVOID lpInBuffer,
	DWORD nInBufferSize,
	LPVOID lpOutBuffer,
	DWORD nOutBufferSize,
	LPDWORD lpBytesRead,
	DWORD nTimeOut);
ROOTRPC_EXPORTED HANDLE RootCreateNamedPipe(
	LPCWSTR lpName,
	DWORD dwOpenMode,
	DWORD dwPipeNode,
	DWORD nMaxInstances,
	DWORD nOutBufferSize,
	DWORD nInBufferSize,
	DWORD nDefaultTimeout,
	LPSECURITY_ATTRIBUTES lpSecurityAttributes);
ROOTRPC_EXPORTED BOOL RootWaitNamedPipe(
	LPCWSTR lpNamedPipeName,
	DWORD nTimeOut);
#endif
#ifndef NO_ROOTRPC_SERVICE_APIS
#endif
#ifdef __cplusplus
}
#endif